﻿using ZYCommon;
using System;
using System.Collections;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using TextEditor.TextDocument.Document;

namespace TextEditor
{


    public class ZYTextElement
    {
        protected bool bolAbsolutePos = false;
        private bool bolVisible = false;
        internal int Index = -1;
        private int intCreatorIndex = -1;
        private int intDeleter = -1;
        protected int intHeight = 0;
        public int intLeft = 0;
        protected int intTop = 0;
        protected int intWidth = 0;
        protected ZYAttributeCollection myAttributes = new ZYAttributeCollection();
        internal bool bolChildElementsLocked = false;  //是否可以插入子元素
        protected ZYTextBorder myBorder = null;
        protected Rectangle myBounds = Rectangle.Empty;
        protected ZYTextDocument myOwnerDocument = null;
        protected ZYTextLine myOwnerLine = null;
        protected ZYTextContainer myParent = null;
        public int WidthFix = 0;

        /***
         * 构造函数
         */
        public ZYTextElement()
        {
            this.myAttributes.OwnerElement = this;
            TempForeColor = Color.Black;
        }

        protected bool BaseFromXML(XmlElement myElement)
        {
            if (myElement != null)
            {
                this.myAttributes.FromXML(myElement);
                if (this.myAttributes.Contains("fontname"))
                {
                    try
                    {
                        if (this.myOwnerDocument.FormatAll)
                        {
                            this.myAttributes.SetValue("xmlfontname", this.myAttributes.GetString("fontname"));
                            this.myAttributes.RemoveAttribute("fontname");
                        }
                    }
                    catch (Exception exception)
                    {
                        MessageBox.Show("系统错误!" + exception.ToString());
                    }
                }
                this.myAttributes.RemoveAttribute("createtime");
                this.myAttributes.RemoveAttribute("deletetime");
                if (myElement.HasAttribute("creator"))
                {
                    this.CreatorIndex = StringCommon.ToInt32Value(myElement.GetAttribute("creator"), 0);
                }
                else
                {
                    this.CreatorIndex = 0;
                }
                if (myElement.HasAttribute("deleter"))
                {
                    this.DeleterIndex = StringCommon.ToInt32Value(myElement.GetAttribute("deleter"), -1);
                }
                else
                {
                    this.DeleterIndex = -1;
                }
                if (this.myBorder != null)
                {
                    this.myBorder.FromXML(myElement);
                }
                this.UpdateAttrubute();
                return true;
            }
            return false;
        }

        public virtual bool CanBeLineEnd()
        {
            return true;
        }

        public virtual bool CanBeLineHead()
        {
            return true;
        }

        public static bool ElementsToXML(ArrayList myList, XmlElement RootElement)
        {
            if ((myList != null) && (RootElement != null))
            {
                foreach (ZYTextElement element in myList)
                {
                    string xMLName = element.GetXMLName();
                    if ((xMLName != null) && XmlReader.IsName(xMLName))
                    {
                        XmlElement myElement = RootElement.OwnerDocument.CreateElement(xMLName);
                        element.ToXML(myElement);
                        RootElement.AppendChild(myElement);
                    }
                }
                return true;
            }
            return false;
        }

        public static bool FixElementsForParent(ArrayList myList)
        {
            if ((myList != null) && (myList.Count > 0))
            {
                for (int i = myList.Count - 1; i >= 0; i--)
                {
                    if (i >= myList.Count)
                    {
                        i = myList.Count - 1;
                    }
                    ZYTextElement element = (ZYTextElement)myList[i];
                    if (myList.Contains(element.Parent))
                    {
                        myList.Remove(element);
                    }
                }
                return true;
            }
            return false;
        }

        public virtual int FixPageLinePos(int LinePos)
        {
            int realTop = this.RealTop;
            if ((LinePos > realTop) && (LinePos < (realTop + this.intHeight)))
            {
                return realTop;
            }
            return -1;
        }

        public virtual bool FromXML(XmlElement myElement)
        {
            return this.BaseFromXML(myElement);
        }

        public static string GetElementsText(ArrayList myList)
        {
            if (myList == null)
            {
                return null;
            }
            StringBuilder builder = new StringBuilder();
            foreach (ZYTextElement element in myList)
            {
                if (element.isTextElement())
                {
                    string str = element.ToZYString();
                    if (str != null)
                    {
                        builder.Append(str);
                    }
                }
            }
            return builder.ToString();
        }

        public virtual string GetXMLName()
        {
            return null;
        }

        public virtual bool HandleClick(int x, int y, MouseButtons Button)
        {
            return false;
        }

        public virtual bool HandleDblClick(int x, int y, MouseButtons Button)
        {
            return false;
        }

        public virtual void HandleEnter()
        {
            if (this.myParent != null)
            {
                this.myParent.HandleEnter();
            }
        }

        public virtual void HandleLeave()
        {
            if (this.myParent != null)
            {
                this.myParent.HandleLeave();
            }
        }

        public virtual bool HandleMouseDown(int x, int y, MouseButtons Button)
        {
            return false;
        }

        public virtual bool HandleMouseMove(int x, int y, MouseButtons Button)
        {
            return false;
        }

        public virtual bool HandleMouseUp(int x, int y, MouseButtons Button)
        {
            return false;
        }

        public virtual bool HandleSelectedChange()
        {
            return false;
        }

        public virtual bool isField()
        {
            return false;
        }

        public virtual bool isNewLine()
        {
            return false;
        }

        public virtual bool isNewParagraph()
        {
            return false;
        }

        public virtual bool isTextElement()
        {
            return true;
        }

        public virtual bool OwnerWholeLine()
        {
            return false;
        }

        public virtual bool RefreshSize()
        {
            return true;
        }

        public virtual bool RefreshView()
        {
            return true;
        }

        public virtual string ToZYString()
        {
            return "";
        }

        public virtual bool ToXML(XmlElement myElement)
        {
            switch (this.myOwnerDocument.Info.SaveMode)
            {
                case 0:
                    this.myAttributes.ToXML(myElement);
                    break;

                case 1:
                    if (this.isField())
                    {
                        myElement.SetAttribute("name", this.myAttributes.GetString("name"));
                        if (StringCommon.isBlankString(this.myAttributes.GetString("id")))
                        {
                            this.myAttributes.SetValue("id", StringCommon.AllocObjectName());
                        }
                        myElement.SetAttribute("id", this.myAttributes.GetString("id"));
                        myElement.InnerText = this.ToZYString();
                    }
                    break;

                case 2:
                    if (this.isField())
                    {
                        myElement.SetAttribute("name", this.myAttributes.GetString("name"));
                        if (StringCommon.isBlankString(this.myAttributes.GetString("id")))
                        {
                            this.myAttributes.SetValue("id", StringCommon.AllocObjectName());
                        }
                        myElement.SetAttribute("id", this.myAttributes.GetString("id"));
                        myElement.InnerText = this.ToZYString();
                    }
                    break;
            }
            return true;
        }

        public virtual void UpdateAttrubute()
        {
            this.intDeleter = StringCommon.ToInt32Value(this.myAttributes.GetString("deleter"), -1);
            this.intCreatorIndex = StringCommon.ToInt32Value(this.myAttributes.GetString("creator"), -1);
        }

        public bool AbsolutePos
        {
            get
            {
                return this.bolAbsolutePos;
            }
            set
            {
                this.bolAbsolutePos = value;
            }
        }

        public ZYAttributeCollection Attributes
        {
            get
            {
                return this.myAttributes;
            }
        }

        public ZYTextBorder Border
        {
            get
            {
                return this.myBorder;
            }
            set
            {
                this.myBorder = value;
            }
        }

        public virtual Rectangle Bounds
        {
            get
            {
                return this.myBounds;
            }
            set
            {
                this.myBounds = value;
            }
        }

        public int CreatorIndex
        {
            get
            {
                return this.intCreatorIndex;
            }
            set
            {
                this.intCreatorIndex = value;
                if (value > 0)
                {
                    this.myAttributes.SetValue("creator", value.ToString());
                }
                else
                {
                    this.myAttributes.RemoveAttribute("creator");
                }
            }
        }

        public int DeleterIndex
        {
            get
            {
                return this.intDeleter;
            }
            set
            {
                this.intDeleter = value;
                if (value >= 0)
                {
                    this.myAttributes.SetValue("deleter", this.intDeleter.ToString());
                }
                else
                {
                    this.myAttributes.RemoveAttribute("deleter");
                }
            }
        }

        public virtual bool Deleteted
        {
            get
            {
                return (this.intDeleter >= 0);
            }
            set
            {
                if (value)
                {
                    if (!Deleteted)
                        this.DeleterIndex = this.myOwnerDocument.SaveLogs.CurrentIndex;
                }
                else
                {
                    this.DeleterIndex = -1;
                }
            }
        }

        public virtual System.Drawing.Font Font
        {
            get
            {
                return this.OwnerDocument.View.DefaultFont;
            }
            set
            {
            }
        }

        public virtual bool FontBold
        {
            get
            {
                return this.OwnerDocument.View.DefaultFont.Bold;
            }
            set
            {
            }
        }

        public virtual bool FontItalic
        {
            get
            {
                return this.OwnerDocument.View.DefaultFont.Italic;
            }
            set
            {
            }
        }

        public virtual string FontName
        {
            get
            {
                return this.OwnerDocument.View.DefaultFont.Name;
            }
            set
            {
            }
        }

        public virtual float FontSize
        {
            get
            {
                return this.OwnerDocument.View.DefaultFont.Size;
            }
            set
            {
            }
        }

        public virtual bool FontUnderLine
        {
            get
            {
                return this.OwnerDocument.View.DefaultFont.Underline;
            }
            set
            {
            }
        }

        public virtual Color ForeColor
        {
            get
            {
                return Color.Black;
            }
            set
            {
            }
        }

        public virtual bool CanDelete
        {
            get
            {
                bool bl = this.myAttributes.GetBool("candelete");
                this.bolChildElementsLocked = bl;
                return bl;
            }
            set
            {
                this.myAttributes.SetValue("candelete", value);
                this.bolChildElementsLocked = value;
            }
        }

        public virtual int Height
        {
            get
            {
                return this.intHeight;
            }
            set
            {
                this.intHeight = value;
            }
        }

        public virtual int Left
        {
            get
            {
                return this.intLeft;
            }
            set
            {
                this.intLeft = value;
            }
        }

        public int LineIndex
        {
            get
            {
                return ((this.myOwnerLine == null) ? 0 : this.myOwnerLine.Index);
            }
        }

        public virtual ZYTextDocument OwnerDocument
        {
            get
            {
                return this.myOwnerDocument;
            }
            set
            {
                this.myOwnerDocument = value;
            }
        }

        public ZYTextLine OwnerLine
        {
            get
            {
                return this.myOwnerLine;
            }
            set
            {
                this.myOwnerLine = value;
            }
        }

        public virtual ZYTextContainer Parent
        {
            get
            {
                return this.myParent;
            }
            set
            {
                this.myParent = value;
            }
        }

        public virtual int RealLeft
        {
            get
            {
                if ((this.myOwnerLine == null) || this.bolAbsolutePos)
                {
                    return this.intLeft;
                }
                return (this.intLeft + this.myOwnerLine.RealLeft);
            }
        }

        public int RealLineIndex
        {
            get
            {
                return ((this.myOwnerLine == null) ? 0 : this.myOwnerLine.RealIndex);
            }
        }

        public virtual int RealTop
        {
            get
            {
                if (this.intTop == 1 && this is ZYTextDiv && this.Parent is ZYTextTableCell)
                {
                    this.intTop = 0;
                }
                if ((this.myOwnerLine == null) || this.bolAbsolutePos)
                {
                    return this.intTop;
                }
                return (this.intTop + this.myOwnerLine.RealTop);
            }
        }

        public virtual int Top
        {
            get
            {
                return this.intTop;
            }
            set
            {
                this.intTop = value;
            }
        }



        internal bool Visible
        {
            get
            {
                return this.bolVisible;
            }
            set
            {
                this.bolVisible = value;
            }
        }

        public virtual int Width
        {
            get
            {
                return this.intWidth;
            }
            set
            {
                this.intWidth = value;
            }
        }

        //**************
        private Color tempForeColor;//记录元素的当前颜色

        public Color TempForeColor
        {
            get { return tempForeColor; }
            set { tempForeColor = value; }
        }

        public string OperaterCreater
        {
            get
            {
                return myAttributes.GetString("operatercreater");
            }
            set
            {

                myAttributes.SetValue("operatercreater", value);
            }
        }

        public string Sign
        {
            get
            {
                return myAttributes.GetString("sign");
            }
            set
            {
                myAttributes.SetValue("sign", value);
            }
        }
    }
}

